from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication,QWidget,QListView
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QFileDialog
from PyQt5.QtCore import *
from Ui_main import Ui_Form
import sys
import cv2
from Face_recognition import *
from Ui_pop_up import Ui_pop_up
import Ui_error_box 
path='face_data.json'
class win(Ui_Form,QWidget):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.listView.clicked.connect(self.on_listview_clicked)
        self.error_win=error_box()
        self.video_Thread=video_Thread()
        self.timer=QTimer()
        self.timer2=QTimer()
        self.face_widget=pop_up()
        self.timer2.timeout.connect(self.up_data_text)
        self.timer.timeout.connect(self.face_video_show)
        self.timer.start(100)
        self.timer2.start(1000)
        self.pushButton_1.clicked.connect(self.Camera)
        self.pushButton_2.clicked.connect(self.Recognition)
        self.pushButton_3.clicked.connect(self.get_face_data)
        self.pushButton_4.clicked.connect(self.pop_face)
        self.face_widget.pushButton_yes.clicked.connect(self.intering)

        
        self.ListView_init()
        
    #已录入的人脸初始化
    def ListView_init(self):
        self.listView.setEditTriggers(QListView.NoEditTriggers)
        self.model = QStringListModel(self.video_Thread.face_reconition.names)
        self.listView.setModel(self.model)
    
    
    #按钮1打开或关闭摄像头
    def Camera(self):
        if self.pushButton_1.text()=="图像采集":
            self.video_Thread.start()
            self.pushButton_1.setText("关闭采集")
               
        elif self.pushButton_1.text()=="关闭采集":
            self.video_Thread.kill()
            self.pushButton_1.setText("图像采集")
            self.pushButton_2.setText("人脸识别")
            self.video_Thread.is_reconition=False
       
    #按钮2识别
    def Recognition(self):
        if self.pushButton_1.text()=="关闭采集":
            if self.pushButton_2.text()=="人脸识别":
                self.video_Thread.is_reconition=True
                self.pushButton_2.setText("取消识别")
            elif self.pushButton_2.text()=="取消识别":
                self.video_Thread.is_reconition=False
                self.pushButton_2.setText("人脸识别")
    #按钮3录入人脸    
    def get_face_data(self):
        if self.pushButton_2.text()=="人脸识别" and self.pushButton_1.text()=="关闭采集":
            self.timer.stop()
            self.video_Thread.kill()
            self.face_frame=self.video_Thread.frame
        
            self.enconding=get_feature(self.face_frame)
            if self.enconding is not None:
                self.face_widget.lineEdit.setText('')
                self.face_widget.show()
            else:
                self.error_win.show()
                self.video_start()
    #按键4减少人脸
    def pop_face(self):
        try:
            self.video_Thread.face_reconition.face_pop(self.listitem)
            self.ListView_init()
        except:
            return
    def video_start(self):
        self.timer.start(100)
        self.video_Thread.start()
    
    #弹窗录入人脸
    def intering(self):
        name=self.face_widget.lineEdit.text()
        if name!='' and self.face_frame is not None:
            self.video_Thread.face_reconition.face_intering(self.face_frame,f'{name}',self.enconding)
            self.video_start()
            self.face_widget.close()
            self.ListView_init()

    #UI显示摄像头画面
    def face_video_show(self):
        frame=self.video_Thread.frame
        if frame is not None:
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            frame=rbox(frame,(480,640))
            image = QImage(frame, 640, 480, QImage.Format_RGB888)
            pixmap = QPixmap.fromImage(image)
            self.video_label.setPixmap(pixmap)
        else:
            self.video_label.clear()
    
    #3秒没有扫到人脸，文字消失
    def up_data_text(self):
        if time.time()-self.video_Thread.text_time>3:
            self.label.setText('')
        
    #获取选中的人脸信息    
    def on_listview_clicked(self, index):
        self.listitem = self.model.data(index, 0)  # 获取选中的数据

import time

#播放摄像头的的线程
class video_Thread(QThread):
    def __init__(self):
        super().__init__()
        self.cap=cv2.VideoCapture(-1)
        self.face_reconition=Face_recognition(path)
        self.frame=None
        self.isrun=False
        self.is_reconition=False
        self.information=None
        self.text_time=0
        
    def run(self):
        self.isrun=True
        while self.isrun:
            _,self.frame=self.cap.read()
            if self.is_reconition:
                self.information=self.face_reconition.face_reading(self.frame)
                if self.information is not None:
                    player.label.setText(self.information[0])
                    self.text_time=time.time()
            
        self.frame=None
    
    def kill(self):
        self.isrun=False
    #输入信息的弹窗 
class pop_up(Ui_pop_up,QWidget):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.pushButton_no.clicked.connect(self.kill)
        
    def kill(self):
        player.video_start()
        self.close()
        
    #错误提示的弹窗    
class error_box(Ui_error_box.Ui_Form,QWidget):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.pushButton.clicked.connect(self.close)
    
    #填充与修改图像的大小
def rbox(frame,new_shape=(480,640)):
    shape = frame.shape[:2]
    r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])        
    new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
    dw, dh = int((new_shape[1] - new_unpad[0])/2),int((new_shape[0] - new_unpad[1])/2)
    frame = cv2.resize(frame, new_unpad)
    frame = cv2.copyMakeBorder(frame, dh, dh, dw, dw, cv2.BORDER_CONSTANT, value=(0,0,0))
    frame = cv2.resize(frame,(new_shape[1],new_shape[0]))
    return frame
        
if __name__ == '__main__':
    app = QApplication(sys.argv)
    player = win()
    player.show()
    sys.exit(app.exec_())